package ModelLayer;

import java.util.Hashtable;

import ServiceLayer.XMLRoomParser;
import android.content.Context;
import android.graphics.Point;

public class Room {
	Context activity;
	public boolean restarting = false;
	public boolean timeOut = false;
	private Tile[][] interactionTiles;
	private int[][] collisionTiles;
	private int[][] map;
	
	private  XMLRoomParser roomParser;
	private int width, height;
	private Point startPosition = new Point(9,9);
	private Hashtable<Point, String> targets;
	private boolean doorTile;
	private String name;
	public int time = 0;
	public boolean timeSet = false;
	public int score;
	
	/**
	 * Creates a default starting room
	 */
	public Room(String newRoom, Context activity){
		System.out.print("\t>>>> ");
		System.err.print("LOADING NEW ROOM: ");
		System.err.println("["+newRoom+"]");
		
		this.activity = activity;
		
		int z = initialize(newRoom);
		
		for (int x=0; x<width; x++){
			for (int y=0; y<height; y++){
				if(map[y][x] == Tile.START_TILE){
					startPosition.x = x;
					startPosition.y = y;
				}
				interactionTiles[x][y] = new Tile(map[y][x]);
				collisionTiles[x][y] = roomParser.getLayeredMap()[z][y][x];
			//	System.out.println("Map[x][y]: "+interactionTiles[x][y].getValue());
			}// System.out.println();
		}
		System.out.println("\n\t\t"+targets.toString());
	}

	
	public Room(String previousRoom, String newRoom, RoomCharacter player, Context activity){
		this.activity = activity;
		System.out.print("\t>>>> ");
		System.err.print("LOADING NEW ROOM: ");
		System.err.println("["+newRoom+"]");
		
		if(previousRoom.equals("")){
			int z = initialize(newRoom);
			
			for (int x=0; x<width; x++){
				for (int y=0; y<height; y++){
					if(map[y][x] == Tile.START_TILE){
						startPosition.x = x;
						startPosition.y = y;
					}
					interactionTiles[x][y] = new Tile(map[y][x]);
					collisionTiles[x][y] = roomParser.getLayeredMap()[z][y][x];
				//	System.out.println("Map[x][y]: "+interactionTiles[x][y].getValue());
				}// System.out.println();
			}
			System.out.println("\n\t\t"+targets.toString());
		} else {
			int z = initialize(newRoom);
			
			String link = "";
			String[] result;
			String from, to;
			for (int x=0; x<width; x++){
				for (int y=0; y<height; y++){
					from = ""; to = "";
					if(map[y][x] == Tile.DOOR_TILE){
						doorTile = true;
						link = targets.get(new Point(x,y));
						if (link.startsWith("rand"))
							break;
						result = link.split("#", 2);
						from = result[0];
						to = result[1];
						if (from.equals(newRoom) && to.equals(previousRoom)){
							switch(player.getFacingDirection()){
							case Direction.DOWN:
								startPosition.x = x;
								startPosition.y = y+1;
								break;
							case Direction.UP:
								startPosition.x = x;
								startPosition.y = y-1;
								break;
							case Direction.LEFT:
								startPosition.x = x-1;
								startPosition.y = y;
								break;
							case Direction.RIGHT:
								startPosition.x = x+1;
								startPosition.y = y;
								break;
							}
							doorTile = false;
						}
					} else if (doorTile) {
					//	startPosition = new Point(7,7);
					}
					interactionTiles[x][y] = new Tile(map[y][x]);
					collisionTiles[x][y] = roomParser.getLayeredMap()[z][y][x];
				//	System.out.println("Map[x][y]: "+interactionTiles[x][y].getValue());
				}// System.out.println();
			}
			System.out.println("\n\t\t"+targets.toString());
		}
	}
	
	public XMLRoomParser getRoomParser() {
		return roomParser;
	}

	public boolean isAdjacentTileEmpty(int direction, Point position) {
		int currentTileId, nextTileId;
		currentTileId = collisionTiles[position.x][position.y];
		
		switch(direction){
		case Direction.UP:
			if(position.y-1 < 0)
				return false;
			nextTileId = collisionTiles[position.x][position.y-1];
		
			for (int i = 0; i < 8; i++)
				if (currentTileId == Wall.up[i] || nextTileId == Wall.down[i]) 
					return false;
			return true;
			
		case Direction.DOWN: 
			if(position.y+1 > height-1)
				return false;
			nextTileId = collisionTiles[position.x][position.y+1];
			for (int i = 0; i < 8; i++)
				if (currentTileId == Wall.down[i] || nextTileId == Wall.up[i]) 
					return false;
			return true;
			
		case Direction.LEFT:
			if(position.x-1 < 0)
				return false;
			nextTileId = collisionTiles[position.x-1][position.y];
			for (int i = 0; i < 8; i++)
				if (currentTileId == Wall.left[i] || nextTileId == Wall.right[i]) 
					return false;
			return true;
			
		case Direction.RIGHT:
			if(position.x+1 > width-1)
				return false;
			nextTileId = collisionTiles[position.x+1][position.y];
			for (int i = 0; i < 8; i++)
				if (currentTileId == Wall.right[i] || nextTileId == Wall.left[i]) 
					return false;
			return true;
		
		default:
			return true;
		}
	}
	
	public Tile getCurrentTile(Point position) {
		return interactionTiles[position.x][position.y];
	}
	
	public Point getStartPosition(){
	
		return startPosition;	
	}
	
	public Hashtable<Point, String> getTargets() {
		return targets;
	}

	private static class Wall{
		static int left[] 	= 	{ 0, 4, 7, 8, 9, 10, 12, 14 };
		static int right[] 	= 	{ 1, 5, 6, 8, 9, 11, 12, 14 };
		static int up[] 	= 	{ 2, 4, 5, 9, 10, 11, 13, 14 };
		static int down[] 	= 	{ 3, 6, 7, 8, 10, 11, 13, 14 };
	}

	private int initialize(String newRoom) {
		name = newRoom;
		String directory = "mapdata/";
		if(!newRoom.endsWith(".xml"))
			roomParser = new XMLRoomParser(directory+newRoom+".xml", activity);
		else 
			roomParser = new XMLRoomParser(directory+newRoom, activity);
		targets = roomParser.getTargets();
		width = roomParser.getRoomWidth();
		height = roomParser.getRoomHeight();
		map = roomParser.getRoomMap();
		interactionTiles = new Tile[width][height];
		collisionTiles = new int[width][height];
		
		int z = roomParser.getCollisionLayer();
		doorTile = false;
		return z;
	}
	
	public String getName(){
		if (!name.endsWith(".xml"))
			return name;
		else
			return name.substring(0, name.length()-4);
	}
}
